package com.crm.miaohe.mapper.interceptor;

import com.crm.miaohe.common.ApplicationConstant;
import com.crm.miaohe.model.BaseModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.Optional;

/**
 * MyBatis拦截器，用来设置创建时间、创建用户、更新时间、更新用户
 *
 * @author leiyongqi
 */
@Slf4j
@Intercepts(@Signature(type = Executor.class, method = ApplicationConstant.MYBATIS_METHOD_UPDATE, args = {MappedStatement.class, Object.class}))
public class MetadataInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 获取jdbc的MappedStatement
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        // 获取插入或更新时的参数
        Object parameter = invocation.getArgs()[1];
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 获取当前用户
        String currentUser = Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication().getName()).orElse("anonymousUser");
        if (parameter instanceof BaseModel) {
            BaseModel entity = (BaseModel) parameter;
            if (SqlCommandType.INSERT.equals(mappedStatement.getSqlCommandType())) {
                // insert时设置创建时间和更新时间，创建用户和更新用户
                entity.setCreateTime(now);
                entity.setUpdateTime(now);
                entity.setCreateUser(currentUser);
                entity.setUpdateUser(currentUser);
                entity.setVersion(0L);
            } else if (SqlCommandType.UPDATE.equals(mappedStatement.getSqlCommandType())) {
                // update时设置更新时间和更新用户
                entity.setUpdateTime(now);
                entity.setUpdateUser(currentUser);
//                if(!ObjectUtils.isEmpty(entity.getVersion())){
//                    entity.setVersion(entity.getVersion() + 1);
//                }
            }
        }
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        if (target instanceof Executor) {
            return Plugin.wrap(target, this);
        } else {
            return target;
        }
    }

}
